package com.trade.common.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.thoughtworks.xstream.core.util.Base64Encoder;
import com.trade.common.utils.crypto.DESUtil;
import com.trade.common.utils.crypto.MD5Util;
import com.trade.common.utils.model.Result;
import com.trade.common.utils.model.Token;
import com.trade.common.utils.net.HttpClientUtil;
import com.trade.common.utils.transform.XmlUtil;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Map;
import java.util.Set;

/**
 * 公共工具类
 */
public class YjhhUtil {

    private static int timeOut = 2000000;

    private static Base64Encoder base64Encoder = new Base64Encoder();
    /**************** MD5Util相关 start ******************/

    /**
     * MD5加密
     *
     * @param str 要加密的字符串
     * @return 加密后的字符串
     */
    public static String encryptMd5(String str) {
        return MD5Util.encryptMd5(str);
    }

    /**************** MD5Util相关 end ******************/

    /**************** DESUtil相关 start ******************/

    /**
     * 数据加密，算法（DES）
     *
     * @param data    要进行加密的数据
     * @param DES_KEY 密钥
     * @return 加密后的数据
     */
    public static String encryptDES(String data, String DES_KEY) {
        return DESUtil.encryptDES(data, DES_KEY);
    }

    /**
     * 数据解密，算法（DES）
     *
     * @param data    加密数据
     * @param DES_KEY 密钥
     * @return 解密后的数据
     */
    public static String decryptDES(String data, String DES_KEY) {
        return DESUtil.decryptDES(data, DES_KEY);
    }

    /**************** DESUtil相关 end ******************/

    /**************** HttpClientUtil相关 start ******************/

    /**
     * 发送post请求-Form格式
     *
     * @param url  请求地址
     * @param pmap 请求参数
     * @return responseContent 远程主机响应正文
     */
    public static String postForm(String url, Map<String, String> pmap) {
        return HttpClientUtil.postForm(url, pmap);
    }

    /**
     * 发送post请求-JSON格式
     *
     * @param url       请求地址
     * @param params    请求参数
     * @param isRaw     是否是raw发送
     * @param tenantId  租户ID（可为空，header传值）
     * @param userId    用户ID（可为空，header传值）
     * @param sessionId 用户会话ID
     * @return responseContent 远程主机响应正文
     */
    public static String post(String url, Map<String, Object> params,
                              boolean isRaw, String tenantId,
                              String userId, String sessionId) {
        return HttpClientUtil.post(url, params, isRaw, tenantId, userId, sessionId);
    }

    /**************** HttpClientUtil相关 end ******************/

    /**************** StringUtils相关 start ******************/

    /**
     * 判断字符串是否为空
     *
     * @param str 要判断的字符串
     * @return
     */
    public static boolean isEmpty(String str) {
        return StringUtils.isEmpty(str);
    }

    /**
     * 判断字符串是否为空，并且不等于"null"
     *
     * @param str 要判断的字符串
     * @return
     */
    public static boolean isEmptyIncludeNull(String str) {
        return StringUtils.isEmpty(str) || "null".equals(str.toLowerCase());
    }

    /**
     * 将对象转换成字符串
     *
     * @param obj 要转换的对象
     * @return
     */
    public static String toString(Object obj) {
        return obj == null ? "" : obj.toString();
    }

    /**
     * 将对象转换成整型
     *
     * @param obj 要转换的对象
     * @return
     */
    public static int toInt(Object obj) {
        return obj == null ? 0 : Integer.valueOf(obj.toString());
    }

    /**************** StringUtils相关 end ******************/

    /**
     * 描述：对象转XML（无格式输出）
     *
     * @param obj 要转换的对象
     * @return 转换后的XML串
     */
    public static String objToXml(Object obj) {
        return XmlUtil.objToXml(obj, false);
    }


    /**
     * 调用远程Service
     *
     * @param params 数据参数（Map格式）
     * @param isRaw  是否是raw发送
     * @return responseContent 远程主机响应正文
     */
    public static Result postJsonCallService(Map<String, Object> params, String ctrlPath, boolean isRaw) {
        Result result = new Result("60", "调用Service失败！");
        try {
            //判断参数
            if (ctrlPath == null || ctrlPath.equals("")) {
                return result.set("60", "参数：ctrlPath不能为空！");
            }
            result.setUrl(ctrlPath);
            //调用
            String postRet = HttpClientUtil.post(ctrlPath, params, isRaw, null, null, null);
            //判断是否是JSON字符串
            result = validateResult(result, postRet);
        } catch (Exception e) {
            result.setError(e.getMessage());
            e.printStackTrace();
        }
        return result;
    }

    private static Result validateResult(Result result, String postRet) {
        if (postRet != null && !postRet.equals("")) {
            if (JsonValidator.validate(postRet)) {
                result = JSON.parseObject(postRet, Result.class);
            } else {
                result.setError(postRet);
            }
        } else {
            result.setError("返回值为：" + postRet);
        }
        return result;
    }

    private static Token validateResult(Token token, String postRet) {
        if (postRet != null && !postRet.equals("")) {
            if (JsonValidator.validate(postRet)) {
                token = JSON.parseObject(postRet, Token.class);
            } else {
                token.setError(postRet);
            }
        } else {
            token.setError("返回值为：" + postRet);
        }
        return token;
    }

    /**
     * 调用远程Service
     *
     * @param pmap 数据参数（Map格式）
     * @return responseContent 远程主机响应正文
     */
    public static Token postFormGetToken(Map<String, String> pmap, Map<String, String> headers, String ctrlPath) {
        Token token = new Token("60", "调用Service失败！");
        try {
            //判断参数
            if (ctrlPath == null || ctrlPath.equals("")) {
                return token.set("60", "参数：ctrlPath不能为空！");
            }
            //调用
            String postRet = HttpClientUtil.postForm(ctrlPath, pmap, headers,
                    "UTF-8", "UTF-8",
                    timeOut, timeOut, timeOut);
            //判断是否是JSON字符串
            token = validateResult(token, postRet);
        } catch (Exception e) {
            token.setError(e.getMessage());
            e.printStackTrace();
        }
        return token;
    }

    /**
     * 调用远程Service
     *
     * @param params 数据参数（Map格式）
     * @return responseContent 远程主机响应正文
     */
    public static Result postFormCallService(Map<String, String> params, Map<String, String> headers, String ctrlPath) {
        Result result = new Result("60", "调用Service失败！");
        try {
            //判断参数
            if (ctrlPath == null || ctrlPath.equals("")) {
                return result.set("60", "参数：ctrlPath不能为空！");
            }
            result.setUrl(ctrlPath);
            //调用
            String postRet = HttpClientUtil.post(ctrlPath, params, headers,
                    "UTF-8", "UTF-8", "application/x-www-form-urlencoded",
                    timeOut, timeOut, timeOut);
            //判断是否是JSON字符串
            result = validateResult(result, postRet);
        } catch (Exception e) {
            result.setError(e.getMessage());
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 发送GET请求
     *
     * @param url       请求地址
     * @param tenantId  租户ID（可为空）
     * @param userId    用户ID（可为空）
     * @param sessionId 用户会话ID
     * @return responseContent 远程主机响应正文
     */
    public static String get(String url, String tenantId, String userId, String sessionId) {
        return HttpClientUtil.get(url, tenantId, userId, sessionId);
    }

    /**
     * 发送delete请求
     *
     * @param url       请求地址
     * @param tenantId  租户ID（可为空）
     * @param userId    用户ID（可为空）
     * @param sessionId 用户会话ID
     * @return responseContent 远程主机响应正文
     */
    public static String delete(String url, String tenantId, String userId, String sessionId) {
        return HttpClientUtil.delete(url, tenantId, userId, sessionId);
    }

    /**
     * 发送put请求
     *
     * @param url       请求地址
     * @param params    参数
     * @param tenantId  租户ID（可为空）
     * @param userId    用户ID（可为空）
     * @param sessionId 用户会话ID
     * @return responseContent 远程主机响应正文
     */
    public static String put(String url, Map<String, Object> params, String tenantId, String userId, String sessionId) {
        return HttpClientUtil.put(url, params, tenantId, userId, sessionId);
    }

    /**
     * post上传文件请求
     *
     * @param url       请求地址
     * @param params    请求参数
     * @param fileNames 文件集合
     * @param tenantId  租户ID（可为空）
     * @param userId    用户ID（可为空）
     * @param sessionId 用户会话ID
     * @return responseContent 远程主机响应正文
     */
    public static String postWithFiles(String url, Map<String, Object> params, String[] fileNames,
                                       String tenantId, String userId, String sessionId) {
        return HttpClientUtil.postWithFiles(url, params, fileNames, tenantId, userId, sessionId);
    }

    /**
     * GET文件下载请求
     *
     * @param url
     * @param filePath 下载目录
     * @param tenantId 租户ID（可为空）
     * @param userId   用户ID（可为空）
     * @param sessionId 用户会话ID
     */
    public static void getWithFile(String url, String filePath, String tenantId, String userId, String sessionId) {
        HttpClientUtil.getWithFile(url, filePath, tenantId, userId, sessionId);
    }


    /**
     * 获取请求参数
     *
     * @param request
     * @param params
     */
    public static void getParams(HttpServletRequest request, Map<String, Object> params) {
        //请求数据处理
        Enumeration paramNames = request.getParameterNames();
        while (paramNames.hasMoreElements()) {
            String paramName = (String) paramNames.nextElement();
            String[] paramValues = request.getParameterValues(paramName);
            if (null != paramValues) {
                if (paramValues.length == 1) {
                    String paramValue = paramValues[0];
                    if (XaUtil.isNotEmpty(paramValue)) {
                        params.put(paramName, paramValue);
                    }
                } else {
                    params.put(paramName, paramValues);
                }
            }
        }

        InputStream is = null;
        String contentStr = "{}";
        try {
            is = request.getInputStream();
            contentStr = IOUtils.toString(is, "utf-8");
            if (XaUtil.isNotEmpty(contentStr)) {
                Object obj = JSON.parse(contentStr);
                if (obj instanceof JSONObject) {
                    JSONObject paramJson = (JSONObject) obj;
                    Set<String> keys = paramJson.keySet();
                    for (String key : keys) {
                        params.put(key, paramJson.get(key));
                    }
                } else if (obj instanceof JSONArray) {
                    JSONArray paramJson = (JSONArray) obj;
                    for (Object objTmp : paramJson) {
                        JSONObject tmpJson = (JSONObject) objTmp;
                        Set<String> keys = tmpJson.keySet();
                        for (String key : keys) {
                            params.put(key, tmpJson.get(key));
                        }
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取代理条件表达式字符串
     *
     * @param conditionJsonArray
     * @return json数组
     */
    public static String getJsonConditions(String conditionJsonArray) {
        // [{"property":"roleName","option":"LIKE","value":"s","propertytype":""},
        // {"property":"roleCode","option":"LIKE","value":"s","propertytype":""},
        // {"property":"roleFlag","option":"EQ","value":"","propertytype":""}]
        StringBuffer conditions = new StringBuffer();
        if (XaUtil.isNotEmpty(conditionJsonArray)) {
            conditions.append("[");
            StringBuffer condition = new StringBuffer();
            String[] filterItems = conditionJsonArray.split("@");//@ %40
            String[] propertyItems = filterItems[0].split("#");//# %23
            String[] optionItems = filterItems[1].split("#");
            String[] valueItems = filterItems[2].split("#");
            String[] propertyTypeItems = filterItems[3].split("#");
            for (int i = 0; i < propertyItems.length; i++) {
                condition.append("{property:\"" + propertyItems[i] + "\",option:\"" + optionItems[i] + "\",value:\"" +
                        getNotNullValue(valueItems[i]) + "\",propertytype:\"" + getNotNullValue(propertyTypeItems[i]) + "\"},");
            }
            conditions.append(condition);
            conditions.deleteCharAt(conditions.length() - 1);
            conditions.append("]");
            /* JSONArray filters = JSONArray.parseArray(conditions.toString());
            for(int i = 0; i < filters.size(); i++){
                System.out.println(filters.get(i));
            }*/
        }
        return conditions.toString();
    }

    /**
     * 转换字符串值为"null"为空字符串""
     *
     * @param value
     * @return
     */
    public static String getNotNullValue(String value) {
        String retValue = "";
        if (XaUtil.isNotEmpty(value) && !"null".equals(value)) {
            retValue = value;
        }
        return retValue;
    }

    /**
     * 获取代理排序表达式字符串
     *
     * @param sortJsonArray
     * @return json数组
     */
    public static String getJsonSorts(String sortJsonArray) {
        StringBuffer sorts = new StringBuffer();
        if (XaUtil.isNotEmpty(sortJsonArray)) {
            sorts.append("[");
            StringBuffer condition = new StringBuffer();
            String[] sortItems = sortJsonArray.split("@");//@ %40
            String[] propertyItems = sortItems[0].split("#");//# %23
            String[] directionItems = sortItems[1].split("#");
            for (int i = 0; i < propertyItems.length; i++) {
                condition.append("{property:\"" + propertyItems[i] + "\",direction:\"" + directionItems[i] + "\"},");
            }
            sorts.append(condition);
            sorts.deleteCharAt(sorts.length() - 1);
            sorts.append("]");
            /*JSONArray sortJsons = JSONArray.parseArray(sorts.toString());
            for(int i = 0; i < sortJsons.size(); i++){
                System.out.println(sortJsons.get(i));
            }*/
        }
        return sorts.toString();
    }

    /**
     * Base64加密
     *
     * @param value
     * @return
     */
    public static String base64Encode(String value) {
        String retValue = "";
        if (XaUtil.isNotEmpty(value) && !"null".equals(value)) {
            retValue = base64Encoder.encode(value.getBytes());
        }
        return retValue;
    }

    /**
     * Base64解密
     *
     * @param value
     * @return
     */
    public static String base64Decode(String value) {
        String retValue = "";
        if (XaUtil.isNotEmpty(value) && !"null".equals(value)) {
            retValue = new String(base64Encoder.decode(value));
        }
        return retValue;
    }
}
